#include <assert.h>
#include <algorithm>
#include <dlfcn.h>
#include <execinfo.h>
#include <iostream>
#include <boost/exception/all.hpp>
#include <boost/throw_exception.hpp>
static std::string callstack()
{
	int j, nptrs;
	#define SIZE 100
	void *buffer[100];
	char **strings;

	nptrs = backtrace(buffer, SIZE);

	/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
	*               would produce similar output to the following: */

	strings = backtrace_symbols(buffer, nptrs);
	if (strings == NULL) {
		perror("backtrace_symbols");
		exit(EXIT_FAILURE);
	}
	std::stringstream ss;
	for(j = 0; j < nptrs; j++) {
		ss << strings[j] << std::endl;
		char syscom[256];
		/*
		sprintf(syscom, "addr2line %p -e hello", buffer[j]);
		system(syscom);
		*/
		Dl_info info;
		dladdr(buffer[j], &info);
		sprintf(syscom, " %s %d\n", info.dli_fname, (unsigned int)((unsigned int)buffer[j] - (unsigned int)info.dli_saddr));
		ss << syscom << std::endl;
	}
	free(strings);
	return ss.str();
}
void fun_a()
{
	throw std::runtime_error(callstack());
}
void fun_b()
{
	fun_a();
}
void fun_c()
{
	fun_b();
}
int main(int argc, char **argv)
{
	try {
		fun_c();
	} catch(std::exception& e)
	{
		std::cout << e.what() << std::endl;
	}
	return 0;
}
